/*
 * Copyright (c) 2023-2025 elsfs Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.elsfs.cloud.common.mybatis.ext.mybatis.extension;

import java.util.Arrays;
import java.util.List;
import lombok.AccessLevel;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.elsfs.cloud.common.core.entity.BaseEntity;

/** 实体关系描述 */
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class EntityRelationDescriptor {

  /** 实体类 */
  private final Class<? extends BaseEntity> entityClass;

  /** 外键字段名称 */
  private final String foreignKeyField;

  /** 连接字段名称 */
  private final String joinKeyField;

  /** 关联选择字段 */
  private final List<String> selectionFields;

  /**
   * 创建实体关联描述对象
   *
   * @param entityClass 实体类
   * @param foreignKeyField 外键字段
   * @param selectionFields 选择字段
   * @return 实体关系描述对象
   */
  public static EntityRelationDescriptor create(
      Class<? extends BaseEntity> entityClass, String foreignKeyField, String... selectionFields) {
    return new EntityRelationDescriptor(
        entityClass, foreignKeyField, null, Arrays.asList(selectionFields));
  }

  /**
   * 创建实体关联描述对象
   *
   * @param entityClass 实体类
   * @param foreignKeyField 外键字段
   * @param selectionFields 选择字段
   * @return 实体关系描述对象
   */
  public static EntityRelationDescriptor create(
      Class<? extends BaseEntity> entityClass, Enum<?> foreignKeyField, String... selectionFields) {
    return new EntityRelationDescriptor(
        entityClass, foreignKeyField.name(), null, Arrays.asList(selectionFields));
  }

  /**
   * 创建一个实体关联描述符构建器
   *
   * @param entityClass 实体类
   * @param foreignKeyField 主表中外键字段名称
   * @return 构建器
   */
  public static EntityRelationDescriptorBuilder builder(
      Class<? extends BaseEntity> entityClass, String foreignKeyField) {
    return new EntityRelationDescriptorBuilder(entityClass, foreignKeyField);
  }

  /**
   * 创建一个实体关联描述符构建器
   *
   * @param entityClass 实体类
   * @param foreignKeyField 主表中外键字段名称枚举
   * @return 构建器
   */
  public static EntityRelationDescriptorBuilder builder(
      Class<? extends BaseEntity> entityClass, Enum<?> foreignKeyField) {
    return new EntityRelationDescriptorBuilder(entityClass, foreignKeyField.name());
  }

  /** 实体关联描述符构建器 */
  @RequiredArgsConstructor
  public static class EntityRelationDescriptorBuilder {
    /** 关联实体类 */
    private final Class<? extends BaseEntity> entityClass;

    /** 外键字段名称 */
    private final String foreignKeyField;

    /** 关联选择字段 */
    private final List<String> selectionFields = Lists.newArrayList();

    /** 连接字段名称 */
    private String joinKeyField;

    /**
     * 设置连接字段
     *
     * @param field 字段名称
     * @return 构建器
     */
    public EntityRelationDescriptorBuilder joinKeyField(String field) {
      this.joinKeyField = field;
      return this;
    }

    /**
     * 设置连接字段
     *
     * @param field 字段名称枚举
     * @return 构建器
     */
    public EntityRelationDescriptorBuilder joinKeyField(Enum<?> field) {
      this.joinKeyField = field.name();
      return this;
    }

    /**
     * 选择字段
     *
     * @param field 字段名称
     * @return 构建器
     */
    public EntityRelationDescriptorBuilder select(String field) {
      this.selectionFields.add(field);
      return this;
    }

    /**
     * 选择字段
     *
     * @param field 字段名称枚举
     * @return 构建器
     */
    public EntityRelationDescriptorBuilder select(Enum<?> field) {
      this.selectionFields.add(field.name());
      return this;
    }

    /**
     * 选择字段
     *
     * @param field 字段名称
     * @param alias 字段别名
     * @return 构建器
     */
    public EntityRelationDescriptorBuilder selectAs(String field, String alias) {
      this.selectionFields.add(field + " AS " + alias);
      return this;
    }

    /**
     * 选择字段
     *
     * @param field 字段名称枚举
     * @param alias 字段别名枚举
     * @return 构建器
     */
    public EntityRelationDescriptorBuilder selectAs(Enum<?> field, Enum<?> alias) {
      this.selectionFields.add(field.name() + " AS " + alias.name());
      return this;
    }

    /**
     * 选择字段
     *
     * @param field 字段名称枚举
     * @param alias 字段别名
     * @return 构建器
     */
    public EntityRelationDescriptorBuilder selectAs(Enum<?> field, String alias) {
      this.selectionFields.add(field.name() + " AS " + alias);
      return this;
    }

    /**
     * 选择字段
     *
     * @param field 字段名称
     * @param alias 字段别名枚举
     * @return 构建器
     */
    public EntityRelationDescriptorBuilder selectAs(String field, Enum<?> alias) {
      this.selectionFields.add(field + " AS " + alias.name());
      return this;
    }

    /**
     * 构建实体关联描述符
     *
     * @return 实体关联描述符
     */
    public EntityRelationDescriptor build() {
      return new EntityRelationDescriptor(
          this.entityClass, this.foreignKeyField, this.joinKeyField, this.selectionFields);
    }
  }
}
